// 接口初探
// function printLabel(labelledObj: { label: string }) {
//   console.log(labelledObj.label)
// }

// let myObj = { size: 10, label: 'size 10 object' }
// printLabel(myObj)

// 重写上述例子- 使用接口
// interface LabelledValue {
//   label: string
// }

// function printLabel(labelledObj: LabelledValue) {
//   console.log(labelledObj.label)
// }
// let myObj = { size: 10, label: 'size 10 object' }
// printLabel(myObj)

// 可选属性
// interface SquareConfig {
//   color?: string
//   width?: number
// }

// function createSquare(config: SquareConfig) : { color: string; area: number } {
//   let newSquare = { color: 'white', area: 100 }
//   if (config.color) {
//     newSquare.color = config.color
//   }
//   if (config.width) {
//     newSquare.area = config.width * config.width
//   }
//   return newSquare
// }

// let mySquare = createSquare({ color: 'black' })

// console.log(mySquare) // { color: 'black', area: 100 }


// 只读属性
// interface Point {
//   readonly x: number
//   readonly y: number
// }

// let p: Point = { x: 1, y: 2 }
// p.x = 4 // 报错

// let a: number[] = [1, 2, 3, 4]
// let ro: ReadonlyArray<number> = a
// ro[0] = 12 // 报错
// ro.push(5) // 报错

// a = ro as number[]
// console.log(a)


// 额外的属性检查
// interface SquareConfig {
//   color?: string
//   width?: number
//   // [propName: string]: any
// }

// function createSquare(config: SquareConfig) : { color: string; area: number } {
//   let newSquare = { color: 'white', area: 100 }
//   if (config.color) {
//     newSquare.color = config.color
//   }
//   if (config.width) {
//     newSquare.area = config.width * config.width
//   }
//   return newSquare
// }

// // let mySquare = createSquare({ colour: 'black', width: 300 } as SquareConfig)
// // let mySquare = createSquare({ colour: 'black', width: 300 })
// let options = { colour: 'black', width: 300 }
// let mySquare = createSquare(options)

// console.log(mySquare) // { color: 'black', area: 100 }

// 函数类型
// interface SearchFunc {
//   (source: string, subString: string): boolean
// }

// let mySearch: SearchFunc = function(source: string, subString: string) {
//   let result = source.search(subString)
//   return result > -1
// }

// console.log(mySearch('hello', 'y'))


// 可索引的类型
// interface StringArray {
//   [index: number]: string
// }
// let myArray: StringArray = ['Bob', 'Fred']
// console.log(myArray[1]) // 'Fred'

// class Animal {
//   name: string
// }

// class Dog extends Animal {
//   breed: string
// }

// interface NotOkay {
//   [x: number]: Animal // 报错：数字索引类型“Animal”不能赋给字符串索引类型“Dog”
//   [y: string]: Dog
// }

// interface NotOkay {
//   [x: number]: Dog
//   [y: string]: Animal
// }

// interface NumberDictionary {
//   [index: string]: number
//   length: number
//   name: string // 报错：类型“string”的属性“name”不能赋给字符串索引类型“number”。
// }

// interface ReadonlyStringArray {
//   readonly [index: number]: string
// }

// let myArray: ReadonlyStringArray = ['Alice', 'Bob']
// myArray[2] = 'Mary' // 报错



// 类类型
// 实现接口
// interface ClockInterface {
//   currentTime: Date
// }

// class Clock implements ClockInterface {
//   currentTime: Date
//   constructor(h: number, m: number) {}
// }

// interface ClockInterface {
//   currentTime: Date
//   setTime(d: Date)
// }

// class Clock implements ClockInterface {
//   currentTime: Date
//   setTime(d: Date) {
//     this.currentTime = d
//   }
//   constructor(h: number, m: number) {}
// }

// 继承接口
// interface Shape {
//   color: string
// }

// interface Square extends Shape {
//   slideLength: number
// }

// let square = <Square>{}
// square.color = 'blue'
// square.slideLength = 10
// console.log(square) // { color: 'blue', slideLength: 10 }

// 一个接口继承多个接口
// interface Shape {
//   color: string
// }
// interface PenStroke {
//   penWidth: number
// }

// interface Square extends Shape, PenStroke {
//   slideLength: number
// }

// let square = <Square>{}
// square.color = 'blue'
// square.slideLength = 10
// square.penWidth = 5.0
// console.log(square) // { color: 'blue', slideLength: 10, penWidth: 5 }

interface Counter {
  (start: number): string
  interval: number
  reset(): void
}

function getCounter(): Counter {
  let counter = <Counter>function (start: number) {}
  counter.interval = 123
  counter.reset = function () {}
  return counter
}

let c = getCounter()
c(10)
c.reset()
c.interval = 5
console.log(c)